package com.ly.system.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ly.common.annotation.DataScope;
import com.ly.common.constant.UserConstants;
import com.ly.common.core.domain.AjaxResult;
import com.ly.common.core.domain.TreeSelect;
import com.ly.common.core.domain.entity.SysDept;
import com.ly.common.core.domain.entity.SysRole;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.StringUtils;
import com.ly.common.utils.erp.ConstUtil;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.system.domain.vo.LoginDeptVo;
import com.ly.system.mapper.SysDeptMapper;
import com.ly.system.mapper.SysRoleMapper;
import com.ly.system.service.ISysDeptService;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;


/**
 * 部门管理 服务实现
 * @author ruoyi
 */
@Service
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements ISysDeptService {

    @Resource
    private SysDeptMapper sysDeptMapper;

    @Resource
    private SysRoleMapper roleMapper;

    /**
     * 查询部门管理数据
     * @param dept 部门信息
     * @return 部门信息集合
     */
    @Override
    @DataScope (deptAlias = "d")
    public List<SysDept> selectDeptList (SysDept dept) {
        dept.setPageNo ( ( dept.getPageNo () - 1 ) * dept.getPageSize () );
        return sysDeptMapper.selectDeptList ( dept );
    }

    @Override
    public Integer queryCount (SysDept sysDept) {
        Integer integer = sysDeptMapper.queryCount ( sysDept );
        return integer;
    }

    /**
     * 构建前端所需要树结构
     * @param depts 部门列表
     * @return 树结构列表
     */
    @Override
    public List<SysDept> buildDeptTree (List<SysDept> depts) {
        List<SysDept> returnList = new ArrayList<SysDept> ();
        List<String> tempList = new ArrayList<> ();
        for ( SysDept dept : depts ) {
            tempList.add ( dept.getDeptId () );
        }
        for ( Iterator<SysDept> iterator = depts.iterator (); iterator.hasNext (); ) {
            SysDept dept = (SysDept) iterator.next ();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if ( ! tempList.contains ( dept.getParentId () ) ) {
                recursionFn ( depts, dept );
                returnList.add ( dept );
            }
        }
        if ( returnList.isEmpty () ) {
            returnList = depts;
        }
        return returnList;
    }

    /**
     * 构建前端所需要下拉树结构
     * @param depts 部门列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildDeptTreeSelect (List<SysDept> depts) {
        List<SysDept> deptTrees = buildDeptTree ( depts );
        return deptTrees.stream ().map ( TreeSelect :: new ).collect ( Collectors.toList () );
    }

    /**
     * 根据角色ID查询部门树信息
     * @param roleId 角色ID
     * @return 选中部门列表
     */
    @Override
    public List<Integer> selectDeptListByRoleId (String roleId) {
        SysRole role = roleMapper.selectRoleById ( roleId );
        return sysDeptMapper.selectDeptListByRoleId ( roleId, role.isDeptCheckStrictly () );
    }

    /**
     * 根据部门ID查询信息
     * @param deptId 部门ID
     * @return 部门信息
     */
    @Override
    public SysDept selectDeptById (String deptId) {
        return sysDeptMapper.selectDeptById ( deptId );
    }

    /**
     * 根据ID查询所有子部门（正常状态）
     * @param deptId 部门ID
     * @return 子部门数
     */
    @Override
    public int selectNormalChildrenDeptById (String deptId) {
        return sysDeptMapper.selectNormalChildrenDeptById ( deptId );
    }

    /**
     * 是否存在子节点
     * @param deptId 部门ID
     * @return 结果
     */
    @Override
    public boolean hasChildByDeptId (String deptId) {
        int result = sysDeptMapper.hasChildByDeptId ( deptId );
        return result > 0 ? true : false;
    }

    /**
     * 查询部门是否存在用户
     * @param deptId 部门ID
     * @return 结果 true 存在 false 不存在
     */
    @Override
    public boolean checkDeptExistUser (String deptId) {
        int result = sysDeptMapper.checkDeptExistUser ( deptId );
        return result > 0 ? true : false;
    }

    /**
     * 校验部门名称是否唯一
     * @param dept 部门信息
     * @return 结果
     */
    @Override
    public String checkDeptNameUnique (SysDept dept) {
        String deptId = StringUtils.isNull ( dept.getDeptId () ) ? "-1" : dept.getDeptId ();
        SysDept info = sysDeptMapper.checkDeptNameUnique ( dept.getDeptName (), dept.getParentId () );
        if ( StringUtils.isNotNull ( info ) && ! info.getDeptId ().equals ( deptId ) ) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 新增保存部门信息
     * @param dept 部门信息
     * @return 结果
     */
    @Override
    public int insertDept (SysDept dept) {
        SysDept info = sysDeptMapper.selectDeptById ( dept.getParentId () );
        //如果没选择上级，则自动挂到最高级别下面
        if ( ObjectUtils.isEmpty ( info ) ) {
            dept.setParentId ( "0" );
            dept.setAncestors ( "0" );
            dept.setLevel ( 0 );
        }
        // 如果父节点不为正常状态,则不允许新增子节点
        if ( ! ObjectUtils.isEmpty ( info ) && ! UserConstants.DEPT_NORMAL.equals ( info.getStatus () ) ) {
            throw new CustomException ( "部门停用，不允许新增" );
        }
        // 选择了上级
        if ( ! ObjectUtils.isEmpty ( info ) ) {
            int level = info.getLevel ();
            dept.setLevel ( ++ level );
            dept.setAncestors ( info.getAncestors () + "," + dept.getParentId () );
            dept.setParentCode ( info.getDeptCode () );
        }
        //ERP录入时自动生成编码，金蝶拉来的编码直接使用，要判重
        if ( StringUtils.isBlank ( dept.getDeptCode () ) ) {
            int count = this.count ( new QueryWrapper<SysDept> ().eq ( "level", dept.getLevel () ) );
            String countStr = String.format ( "%06d", count );
            if ( dept.getLevel () == ConstUtil.DEPT_LEVEL_GROUP ) {
                dept.setDeptCode ( "GROUP".concat ( countStr ) );
            } else if ( dept.getLevel () == ConstUtil.DEPT_LEVEL_COMPANY ) {
                dept.setDeptCode ( "ZGS".concat ( countStr ) );
            } else if ( dept.getLevel () == ConstUtil.DEPT_LEVEL_DEPT ) {
                dept.setDeptCode ( "BM".concat ( countStr ) );
            }
        }
        dept.setDeptId ( SnowflakeIdWorker.getInstance ().nextStringId () );
        dept.setCreateBy ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
        dept.setCreateTime ( DateUtils.getNowDate () );
//        return sysDeptMapper.insertDept ( dept );
        boolean save = this.save ( dept );
        return save ? 1 : 0 ;
    }

    /**
     * 修改保存部门信息
     * @param dept 部门信息
     * @return 结果
     */
    @Override
    public AjaxResult updateDept (SysDept dept) {
        SysDept newParentDept = sysDeptMapper.selectDeptById ( dept.getParentId () );
        if ( newParentDept == null ) {
            return AjaxResult.error ( "上级部门不能为空！" );
        }
        SysDept oldDept = sysDeptMapper.selectDeptById ( dept.getDeptId () );
        if ( StringUtils.isNotNull ( newParentDept ) && StringUtils.isNotNull ( oldDept ) ) {
            String newAncestors = newParentDept.getAncestors () + "," + newParentDept.getDeptId ();
            String oldAncestors = oldDept.getAncestors ();
            dept.setAncestors ( newAncestors );
            updateDeptChildren ( dept.getDeptId (), newAncestors, oldAncestors );
        }
        //修改Level
        Integer level = newParentDept.getLevel ();
        dept.setLevel ( ++ level );
        int result = sysDeptMapper.updateDept ( dept );
        if ( result == 0 ) {
            throw new CustomException ( "更新部门失败！" );
        }
        if ( UserConstants.DEPT_NORMAL.equals ( dept.getStatus () ) ) {
            // 如果该部门是启用状态，则启用该部门的所有上级部门
            updateParentDeptStatus ( dept );
        }
        return AjaxResult.success ( "修改成功" );
    }

    /**
     * 修改该部门的父级部门状态
     * @param dept 当前部门
     */
    private void updateParentDeptStatus (SysDept dept) {
        String updateBy = dept.getUpdateBy ();
        dept = sysDeptMapper.selectDeptById ( dept.getDeptId () );
        dept.setUpdateBy ( updateBy );
        sysDeptMapper.updateDeptStatus ( dept );
    }

    /**
     * 修改子元素关系
     * @param deptId       被修改的部门ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateDeptChildren (String deptId, String newAncestors, String oldAncestors) {
        List<SysDept> children = sysDeptMapper.selectChildrenDeptById ( deptId );
        for ( SysDept child : children ) {
            child.setAncestors ( child.getAncestors ().replace ( oldAncestors, newAncestors ) );
        }
        if ( children.size () > 0 ) {
            sysDeptMapper.updateDeptChildren ( children );
        }
    }

    /**
     * 删除部门管理信息
     * @param deptId 部门ID
     * @return 结果
     */
    @Override
    public int deleteDeptById (String deptId) {
        return sysDeptMapper.deleteDeptById ( deptId );
    }

    /**
     * 递归列表
     */
    private void recursionFn (List<SysDept> list, SysDept t) {
        // 得到子节点列表
        List<SysDept> childList = getChildList ( list, t );
        t.setChildren ( childList );
        for ( SysDept tChild : childList ) {
            if ( hasChild ( list, tChild ) ) {
                recursionFn ( list, tChild );
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SysDept> getChildList (List<SysDept> list, SysDept t) {
        List<SysDept> tlist = new ArrayList<SysDept> ();
        Iterator<SysDept> it = list.iterator ();
        while ( it.hasNext () ) {
            SysDept n = (SysDept) it.next ();
            if ( StringUtils.isNotNull ( n.getParentId () ) && n.getParentId ().equals ( t.getDeptId () ) ) {
                tlist.add ( n );
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild (List<SysDept> list, SysDept t) {
        return getChildList ( list, t ).size () > 0 ? true : false;
    }


    @Override
    public List<LoginDeptVo> getDeptOption () {
        List<SysDept> deptList = this.list ( new QueryWrapper<SysDept> ().eq ( "level", 1 ) );
        List<LoginDeptVo> list = new ArrayList<> ();
        if ( CollectionUtil.isNotEmpty ( deptList ) ) {
            list = deptList.stream ().map ( dept -> {
                LoginDeptVo deptVo = new LoginDeptVo ().setDeptId ( dept.getDeptId () ).setName ( dept.getDeptName () );
                return deptVo;
            } ).collect ( Collectors.toList () );
        }
        return list;
    }


}
